{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Introduction to Prompt Engineering Tutorial\n",
    "\n",
    "## Overview\n",
    "\n",
    "This tutorial provides a comprehensive introduction to the fundamental concepts of prompt engineering in the context of AI and language models. It is designed to give learners a solid foundation in understanding how to effectively communicate with and leverage large language models through carefully crafted prompts.\n",
    "\n",
    "## Motivation\n",
    "\n",
    "As AI language models become increasingly sophisticated and widely used, the ability to interact with them effectively becomes a crucial skill. Prompt engineering is the key to unlocking the full potential of these models, allowing users to guide AI outputs, improve response quality, and tackle complex tasks. This tutorial aims to equip learners with the essential knowledge and skills to begin their journey in prompt engineering.\n",
    "\n",
    "## Key Components\n",
    "\n",
    "The tutorial covers several key components of prompt engineering:\n",
    "\n",
    "1. **Basic Concepts**: An introduction to what prompt engineering is and why it's important.\n",
    "2. **Prompt Structures**: Exploration of different ways to structure prompts for various outcomes.\n",
    "3. **Importance of Prompt Engineering**: Discussion on how prompt engineering impacts AI model performance.\n",
    "4. **Role in AI and Language Models**: Examination of how prompt engineering fits into the broader context of AI applications.\n",
    "5. **Practical Examples**: Hands-on demonstrations of prompt engineering techniques.\n",
    "\n",
    "## Method Details\n",
    "\n",
    "The tutorial employs a mix of theoretical explanations and practical demonstrations to convey the concepts of prompt engineering:\n",
    "\n",
    "1. **Setup and Environment**: The lesson begins by setting up the necessary tools, including the OpenAI API and LangChain library. This provides a practical environment for experimenting with prompts.\n",
    "\n",
    "2. **Basic Concept Exploration**: Through simple examples, learners are introduced to how different prompts can yield varying responses from the AI model. This illustrates the fundamental principle of prompt engineering.\n",
    "\n",
    "3. **Structured Prompts**: The tutorial demonstrates how to create more complex, structured prompts using LangChain's PromptTemplate. This shows how to create reusable prompt structures with variable inputs.\n",
    "\n",
    "4. **Comparative Analysis**: By presenting multiple prompts on the same topic, the lesson highlights how subtle changes in prompt structure and wording can significantly affect the AI's output.\n",
    "\n",
    "5. **Problem-Solving Application**: The tutorial explores how prompt engineering can be applied to break down complex problems, guiding the AI through a step-by-step reasoning process.\n",
    "\n",
    "6. **Limitation Mitigation**: Examples are provided to show how careful prompt design can help overcome some limitations of AI models, such as improving factual accuracy.\n",
    "\n",
    "Throughout these methods, the tutorial emphasizes the importance of clarity, specificity, and thoughtful design in creating effective prompts.\n",
    "\n",
    "## Conclusion\n",
    "\n",
    "This introductory tutorial on prompt engineering lays the groundwork for understanding and applying this crucial skill in AI interactions. By the end of the lesson, learners will have gained:\n",
    "\n",
    "1. A clear understanding of what prompt engineering is and why it's important.\n",
    "2. Insight into how different prompt structures can influence AI outputs.\n",
    "3. Practical experience in crafting prompts for various purposes.\n",
    "4. Awareness of the role prompt engineering plays in enhancing AI model performance.\n",
    "5. A foundation for exploring more advanced prompt engineering techniques.\n",
    "\n",
    "The skills and knowledge gained from this tutorial will enable learners to more effectively harness the power of AI language models, setting the stage for more advanced applications and explorations in the field of artificial intelligence."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Setup\n",
    "\n",
    "First, let's import the necessary libraries"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import os\n",
    "from langchain_openai import ChatOpenAI\n",
    "from langchain.prompts import PromptTemplate\n",
    "\n",
    "from dotenv import load_dotenv\n",
    "load_dotenv()\n",
    "\n",
    "os.environ[\"OPENAI_API_KEY\"] = os.getenv('OPENAI_API_KEY') # OpenAI API key\n",
    "# Initialize the language model\n",
    "llm = ChatOpenAI(model=\"gpt-4o-mini\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Basic Concepts and Importance\n",
    "\n",
    "Prompt engineering is the practice of designing and optimizing input prompts for language models to generate desired outputs. It's a crucial skill for effectively leveraging AI models in various applications.\n",
    "\n",
    "Let's explore the concept with a simple example:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Prompt engineering is the process of designing and refining input prompts to optimize the responses generated by artificial intelligence models, enhancing their performance and relevance for specific tasks.\n"
     ]
    }
   ],
   "source": [
    "basic_prompt = \"Explain the concept of prompt engineering in one sentence.\"\n",
    "print(llm.invoke(basic_prompt).content)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now, let's see how a more structured prompt can yield a more detailed response:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "### Definition of Prompt Engineering\n",
      "\n",
      "Prompt engineering is the process of designing and refining input prompts to effectively communicate with artificial intelligence (AI) models, particularly large language models (LLMs) like GPT-3 or GPT-4. This involves crafting specific, clear, and contextually appropriate prompts to elicit desired responses from the AI, optimizing the interaction to achieve better performance, accuracy, and relevance of the outputs.\n",
      "\n",
      "### Importance of Prompt Engineering\n",
      "\n",
      "Prompt engineering is crucial because it directly influences the quality and usefulness of the responses generated by AI models. As these models are trained on vast datasets, the way questions or requests are framed can significantly impact their ability to understand context, intent, and nuances. Effective prompt engineering can enhance the overall user experience, making AI tools more accessible and valuable for various applications, from content creation to customer service.\n",
      "\n",
      "### Key Benefits of Prompt Engineering\n",
      "\n",
      "1. **Enhanced Output Quality**:\n",
      "   - Well-crafted prompts can lead to more accurate, relevant, and coherent responses from AI models. This results in higher-quality outputs that meet user expectations and needs.\n",
      "\n",
      "2. **Increased Efficiency**:\n",
      "   - By optimizing prompts, users can save time and resources, reducing the number of iterations needed to achieve a satisfactory response. This efficiency is especially valuable in professional settings where time is of the essence.\n",
      "\n",
      "3. **Broader Applicability**:\n",
      "   - Effective prompt engineering allows users to tailor AI interactions to specific use cases, making AI more versatile. This adaptability can be applied across various domains, such as education, marketing, and research, enabling more innovative and impactful applications of AI technology.\n"
     ]
    }
   ],
   "source": [
    "structured_prompt = PromptTemplate(\n",
    "    input_variables=[\"topic\"],\n",
    "    template=\"Provide a definition of {topic}, explain its importance, and list three key benefits.\"\n",
    ")\n",
    "\n",
    "chain = structured_prompt | llm # Combine the prompt template with the language model\n",
    "input_variables = {\"topic\": \"prompt engineering\"} # Define the input variables\n",
    "output = chain.invoke(input_variables).content # Invoke the chain with the input variables\n",
    "print(output)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Importance of Prompt Engineering\n",
    "\n",
    "Prompt engineering is important because it allows us to:\n",
    "1. Improve the quality and relevance of AI-generated outputs\n",
    "2. Guide language models to perform specific tasks more effectively\n",
    "3. Overcome limitations and biases in AI models\n",
    "4. Customize AI responses for different use cases and audiences\n",
    "\n",
    "Let's demonstrate how different prompts can lead to different outputs on the same topic:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Prompt 1:\n",
      "List 3 applications of AI in healthcare.\n",
      "\n",
      "Response:\n",
      "Here are three applications of AI in healthcare:\n",
      "\n",
      "1. **Medical Imaging and Diagnostics**: AI algorithms, particularly those based on deep learning, are used to analyze medical images (such as X-rays, MRIs, and CT scans) to assist radiologists in diagnosing conditions like tumors, fractures, and other abnormalities. These systems can enhance accuracy and speed in detecting diseases, often identifying issues that may be missed by human eyes.\n",
      "\n",
      "2. **Predictive Analytics for Patient Outcomes**: AI can analyze large datasets from electronic health records (EHRs) to predict patient outcomes, such as the likelihood of readmission, progression of diseases, or response to specific treatments. This application helps healthcare providers make informed decisions about patient care and improve overall treatment plans.\n",
      "\n",
      "3. **Personalized Medicine**: AI is used to tailor treatment plans to individual patients by analyzing genetic information, lifestyle data, and other personal health factors. This approach allows for more effective and targeted therapies, especially in areas like oncology, where understanding the genetic makeup of tumors can lead to better treatment options. \n",
      "\n",
      "These applications demonstrate how AI is transforming healthcare by improving diagnostics, enhancing patient care, and personalizing treatment.\n",
      "--------------------------------------------------\n",
      "\n",
      "Prompt 2:\n",
      "Explain how AI is revolutionizing healthcare, with 3 specific examples.\n",
      "\n",
      "Response:\n",
      "AI is significantly transforming healthcare by enhancing diagnostics, personalizing treatment, and optimizing operational efficiency. Here are three specific examples:\n",
      "\n",
      "1. **Diagnostic Imaging**:\n",
      "   AI algorithms, particularly deep learning models, are being applied to medical imaging to improve the accuracy and speed of diagnoses. For instance, AI systems can analyze X-rays, MRIs, and CT scans to detect anomalies such as tumors, fractures, or other conditions with remarkable precision. A notable example is Google's DeepMind, which developed an AI system that can detect eye diseases from retinal scans with accuracy that matches or surpasses that of human experts. This capability not only speeds up the diagnostic process but also helps in identifying issues that may sometimes be missed by human radiologists.\n",
      "\n",
      "2. **Predictive Analytics for Patient Outcomes**:\n",
      "   AI is being used to predict patient outcomes and identify those at risk for complications or readmissions. For example, algorithms can analyze vast amounts of patient data, including medical history, lab results, and demographic information, to identify patterns that indicate a higher likelihood of adverse events. Hospitals like Mount Sinai have implemented AI-driven tools that analyze electronic health records to predict which patients are at risk of developing conditions like sepsis. By flagging these patients early, healthcare providers can intervene promptly, improving outcomes and potentially saving lives.\n",
      "\n",
      "3. **Personalized Medicine**:\n",
      "   AI is playing a crucial role in the development of personalized treatment plans based on an individual’s unique genetic makeup and lifestyle factors. For instance, companies like Tempus utilize AI to analyze clinical and molecular data to help oncologists tailor cancer treatments to individual patients. By processing genomic sequencing data and correlating it with treatment outcomes, AI helps identify which therapies are likely to be most effective for specific patients, thereby enhancing the efficacy of treatment and minimizing unnecessary side effects.\n",
      "\n",
      "Together, these examples illustrate how AI is not only improving diagnostic accuracy and patient outcomes but also fostering a more personalized and efficient healthcare system.\n",
      "--------------------------------------------------\n",
      "\n",
      "Prompt 3:\n",
      "You are a doctor. Describe 3 ways AI has improved your daily work in the hospital.\n",
      "\n",
      "Response:\n",
      "As a doctor, AI has significantly transformed my daily work in several ways:\n",
      "\n",
      "1. **Enhanced Diagnostic Accuracy**: AI-powered diagnostic tools help analyze medical images, such as X-rays, MRIs, and CT scans, with remarkable precision. These systems can identify patterns and anomalies that might be overlooked by the human eye, leading to earlier and more accurate diagnoses. For instance, AI algorithms can assist in detecting early signs of diseases like cancer, allowing for timely intervention and better patient outcomes.\n",
      "\n",
      "2. **Streamlined Administrative Tasks**: AI has automated various administrative processes, such as scheduling appointments, managing patient records, and processing insurance claims. Tools like natural language processing (NLP) enable voice recognition for clinical documentation, reducing the time spent on paperwork. This efficiency allows me to focus more on patient care rather than administrative burdens, ultimately improving the overall patient experience.\n",
      "\n",
      "3. **Personalized Treatment Plans**: AI analyzes vast amounts of patient data, including genetic information, treatment history, and lifestyle factors, to help create personalized treatment plans. By leveraging predictive analytics, AI can identify the most effective interventions for individual patients, considering their unique circumstances. This tailored approach not only enhances the effectiveness of treatments but also fosters better patient engagement and adherence to medical advice.\n",
      "\n",
      "Overall, AI has become an invaluable tool in my practice, enhancing diagnostic capabilities, improving efficiency, and enabling more personalized patient care.\n",
      "--------------------------------------------------\n"
     ]
    }
   ],
   "source": [
    "prompts = [\n",
    "    \"List 3 applications of AI in healthcare.\",\n",
    "    \"Explain how AI is revolutionizing healthcare, with 3 specific examples.\",\n",
    "    \"You are a doctor. Describe 3 ways AI has improved your daily work in the hospital.\"\n",
    "]\n",
    "\n",
    "for i, prompt in enumerate(prompts, 1):\n",
    "    print(f\"\\nPrompt {i}:\")\n",
    "    print(prompt)\n",
    "    print(\"\\nResponse:\")\n",
    "    print(llm.invoke(prompt).content)\n",
    "    print(\"-\" * 50)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Role in AI and Language Models\n",
    "\n",
    "Prompt engineering plays a crucial role in enhancing the performance and applicability of AI and language models. It helps in:\n",
    "\n",
    "1. Tailoring model outputs to specific needs\n",
    "2. Improving the accuracy and relevance of responses\n",
    "3. Enabling complex task completion\n",
    "4. Reducing biases and improving fairness in AI outputs\n",
    "\n",
    "Let's explore how prompt engineering can help in overcoming some limitations of language models:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Evaluation: The statement is incorrect. The capital of France is Paris, not London.\n"
     ]
    }
   ],
   "source": [
    "fact_check_prompt = PromptTemplate(\n",
    "    input_variables=[\"statement\"],\n",
    "    template=\"\"\"Evaluate the following statement for factual accuracy. If it's incorrect, provide the correct information:\n",
    "    Statement: {statement}\n",
    "    Evaluation:\"\"\"\n",
    ")\n",
    "\n",
    "chain = fact_check_prompt | llm\n",
    "print(chain.invoke(\"The capital of France is London.\").content)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Improving Complex Problem-Solving\n",
    "\n",
    "Prompt engineering can also help in breaking down complex problems and guiding the model through a step-by-step reasoning process:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "To calculate the compound interest on an investment, we can use the formula for compound interest:\n",
      "\n",
      "\\[\n",
      "A = P(1 + r/n)^{nt}\n",
      "\\]\n",
      "\n",
      "Where:\n",
      "- \\( A \\) = the amount of money accumulated after n years, including interest.\n",
      "- \\( P \\) = the principal amount (the initial amount of money).\n",
      "- \\( r \\) = annual interest rate (decimal).\n",
      "- \\( n \\) = number of times that interest is compounded per year.\n",
      "- \\( t \\) = the number of years the money is invested or borrowed.\n",
      "\n",
      "In this problem:\n",
      "- \\( P = 1000 \\) (the principal amount)\n",
      "- \\( r = 0.05 \\) (5% annual interest rate expressed as a decimal)\n",
      "- \\( n = 1 \\) (interest is compounded annually)\n",
      "- \\( t = 5 \\) (the number of years)\n",
      "\n",
      "Now, we will calculate step by step:\n",
      "\n",
      "### Step 1: Substitute the values into the formula\n",
      "\n",
      "\\[\n",
      "A = 1000 \\left(1 + \\frac{0.05}{1}\\right)^{1 \\times 5}\n",
      "\\]\n",
      "\n",
      "### Step 2: Simplify the expression inside the parentheses\n",
      "\n",
      "\\[\n",
      "A = 1000 \\left(1 + 0.05\\right)^{5}\n",
      "\\]\n",
      "\\[\n",
      "A = 1000 \\left(1.05\\right)^{5}\n",
      "\\]\n",
      "\n",
      "### Step 3: Calculate \\( (1.05)^{5} \\)\n",
      "\n",
      "Using a calculator or by manual computation:\n",
      "\\[\n",
      "(1.05)^{5} \\approx 1.2762815625\n",
      "\\]\n",
      "\n",
      "### Step 4: Multiply by the principal amount\n",
      "\n",
      "Now, we substitute back to find \\( A \\):\n",
      "\n",
      "\\[\n",
      "A = 1000 \\times 1.2762815625 \\approx 1276.28\n",
      "\\]\n",
      "\n",
      "### Step 5: Calculate the compound interest\n",
      "\n",
      "The compound interest can be found by subtracting the principal from the total amount:\n",
      "\n",
      "\\[\n",
      "\\text{Compound Interest} = A - P\n",
      "\\]\n",
      "\\[\n",
      "\\text{Compound Interest} = 1276.28 - 1000 \\approx 276.28\n",
      "\\]\n",
      "\n",
      "### Final Result\n",
      "\n",
      "The compound interest on $1000 invested for 5 years at an annual rate of 5%, compounded annually, is approximately **$276.28**.\n"
     ]
    }
   ],
   "source": [
    "problem_solving_prompt = PromptTemplate(\n",
    "    input_variables=[\"problem\"],\n",
    "    template=\"\"\"Solve the following problem step by step:\n",
    "    Problem: {problem}\n",
    "    Solution:\n",
    "    1)\"\"\"\n",
    ")\n",
    "\n",
    "chain = problem_solving_prompt | llm\n",
    "print(chain.invoke(\"Calculate the compound interest on $1000 invested for 5 years at an annual rate of 5%, compounded annually.\").content)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": ".venv",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.12.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
